using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.GamerServices;

namespace TimeWar
{

    public enum CameraTypes
    {
        MapView,
        ChaseView,
    }

    public abstract class Camera
    {

        protected float aspectRatio = 16 / 9;
        protected float viewAngle = MathHelper.PiOver4;
        //private float viewAngle = MathHelper.PiOver2;

        protected float nearClip = 0.00001f;
        protected float farClip = 2000.0f;

        /// <summary>
        /// A global projection matrix since it never changes
        /// </summary>
        protected Matrix projection;

        /// <summary>
        /// A global view matrix since it never changes
        /// </summary>
        protected Matrix view;

        protected Quaternion rotation;

        /// <summary>
        /// The Camera position which never changes
        /// </summary>
        protected Vector3 position;


        #region Properties

        public Matrix RotationMatrix
        {
            get
            {
                Matrix rotationMatrix = Matrix.CreateFromQuaternion(rotation);
                return rotationMatrix;
            }
        }

        public Matrix Projection
        {
            get
            {
                return projection;
            }
        }

        public Matrix View
        {
            get
            {
                return view;
            }
        }

        public Vector3 Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
            }
        }

        public float AspectRatio
        {
            get
            {
                return aspectRatio;
            }
            set
            {
                aspectRatio = value;
            }
        }

        public float ViewAngle
        {
            get
            {
                return viewAngle;
            }
            set
            {
                viewAngle = value;
            }
        }

        public float NearClip
        {
            get
            {
                return nearClip;
            }
            set
            {
                nearClip = value;
            }
        }

        public float FarClip
        {
            get
            {
                return farClip;
            }
            set
            {
                farClip = value;
            }
        }

        #endregion Properties

        #region Frustrum related
        protected BoundingFrustum _frustum;
        /// <summary>   
        /// The trapezoid that contains everything that the camera can see.   
        /// </summary>   
        public BoundingFrustum Frustum
        {
            get { return _frustum; }
        }

        protected BoundingFrustum _reflectedFrustum;
        /// <summary>   
        /// The trapezoid that contains everything that the camera can see if it was reflected.   
        /// </summary>   
        public BoundingFrustum ReflectedFrustum
        {
            get { return _reflectedFrustum; }
        }

        protected Matrix reflectedView;   
        /// <summary>   
        /// Reflected View matrix around an arbitrary plane.   
        /// </summary>   
        public Matrix ReflectedView
        {
            get { return reflectedView; }
            set { reflectedView = value; }
        }

        protected void updateFrustrum()
        {
            _frustum = new BoundingFrustum(Matrix.Multiply(view, projection));
            _reflectedFrustum = new BoundingFrustum(Matrix.Multiply(reflectedView, projection));   
  
        }


        #endregion Frustrum related

        public Camera()
        {
            _frustum = new BoundingFrustum(Matrix.Identity);
            _reflectedFrustum = new BoundingFrustum(Matrix.Identity);
        }

        public abstract void Update(Vector3 objPosition, Quaternion objRotation);

    }
}